package system

import (
	"errors"
	"fmt"
	"ltbz/cultural_tourism_api/models/system"
	"ltbz/cultural_tourism_api/utils"
	"strconv"
	"strings"
)

func DeptTreeList(req *system.DeptListReq, startSize, pageSize int) (count int, list []*system.DeptListItemResp, err error, errMsg string) {
	dept := new(system.SysDept)

	var condition string
	var pars []interface{}

	//根据名称找到所有最顶层的节点
	var finalRootIds []string
	if req.DeptName != "" {
		var rootIds []string
		deptName := "%" + req.DeptName + "%"
		relationList, tErr := dept.GetDeptByName(deptName)
		if tErr != nil {
			errMsg = "查询部门出错"
			err = errors.New(errMsg + "Err:" + tErr.Error())
			return
		}
		if len(relationList) == 0 { //查不到相关记录
			return
		}
		for _, v := range relationList {
			if v.RootId == 0 {
				rootIds = append(rootIds, strconv.Itoa(int(v.DeptId)))
			} else {
				rootIds = append(rootIds, strconv.Itoa(int(v.RootId)))
			}
		}
		//分页处理 查询最顶层结点，得到最终的顶层结点
		condition = " AND parent_id=0 AND dept_id IN(" + strings.Join(rootIds, ",") + ")"
		//pars = append(pars, rootIds)
	} else {
		condition = " AND parent_id=0"
	}

	count, err = dept.GetSysDeptPageCount(condition, pars)

	rootList, err := dept.GetSysDeptPage(condition, pars, startSize, pageSize)
	if err != nil {
		errMsg = "查询部门列表出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	if len(rootList) == 0 { //查不到相关记录
		return
	}
	for _, v := range rootList {
		finalRootIds = append(finalRootIds, strconv.Itoa(int(v.DeptId)))
	}
	finalRootIdsStr := strings.Join(finalRootIds, ",")
	//查询所有该顶层节点下的子节点
	fCondition := " AND (root_id IN (" + finalRootIdsStr + ") OR dept_id IN (" + finalRootIdsStr + "))"
	fPars := make([]interface{}, 0)
	//fPars = append(fPars, finalRootIds, finalRootIds)
	orderStr := " sort ASC, dept_id DESC"
	childList, err := dept.GetDeptListByCondition(fCondition, fPars, orderStr)
	if err != nil {
		errMsg = "查询部门列表出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}

	list = make([]*system.DeptListItemResp, 0)
	for _, v := range childList {
		tmp := &system.DeptListItemResp{
			DeptId:     v.DeptId,
			ParentId:   v.ParentId,
			DeptName:   v.DeptName,
			Sort:       v.Sort,
			CreateTime: v.CreateTime.Format(utils.FormatDateTime),
			ModifyTime: v.ModifyTime.Format(utils.FormatDateTime),
			Children:   nil,
		}
		list = append(list, tmp)
	}
	//组装返回值
	list = getDeptTreeRecursive(list, 0)
	return
}

func DeptTreeAll(req *system.DeptAllReq) (list []*system.DeptListItemResp, err error, errMsg string) {
	dept := new(system.SysDept)

	var condition string
	var pars []interface{}

	//根据名称找到所有最顶层的节点
	var finalRootIds []string
	if req.DeptName != "" {
		var rootIds []string
		deptName := "%" + req.DeptName + "%"
		relationList, tErr := dept.GetDeptByName(deptName)
		if tErr != nil {
			errMsg = "查询部门出错"
			err = errors.New(errMsg + "Err:" + tErr.Error())
			return
		}
		if len(relationList) == 0 { //查不到相关记录
			return
		}
		for _, v := range relationList {
			if v.RootId == 0 {
				rootIds = append(rootIds, strconv.Itoa(int(v.DeptId)))
			} else {
				rootIds = append(rootIds, strconv.Itoa(int(v.RootId)))
			}
		}
		//分页处理 查询最顶层结点，得到最终的顶层结点
		condition = " AND parent_id=0 AND dept_id IN(" + strings.Join(rootIds, ",") + ")"
		//pars = append(pars, rootIds)
	} else {
		condition = " AND parent_id=0"
	}

	rootList, err := dept.GetSysDeptAll(condition, pars, "")
	if err != nil {
		errMsg = "查询部门列表出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	if len(rootList) == 0 { //查不到相关记录
		return
	}
	for _, v := range rootList {
		finalRootIds = append(finalRootIds, strconv.Itoa(int(v.DeptId)))
	}
	finalRootIdsStr := strings.Join(finalRootIds, ",")
	//查询所有该顶层节点下的子节点
	fCondition := " AND (root_id IN (" + finalRootIdsStr + ") OR dept_id IN (" + finalRootIdsStr + "))"
	fPars := make([]interface{}, 0)
	//fPars = append(fPars, finalRootIds, finalRootIds)
	orderStr := " sort ASC, dept_id DESC"
	childList, err := dept.GetDeptListByCondition(fCondition, fPars, orderStr)
	if err != nil {
		errMsg = "查询部门列表出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}

	list = make([]*system.DeptListItemResp, 0)
	for _, v := range childList {
		tmp := &system.DeptListItemResp{
			DeptId:     v.DeptId,
			ParentId:   v.ParentId,
			DeptName:   v.DeptName,
			Sort:       v.Sort,
			CreateTime: v.CreateTime.Format(utils.FormatDateTime),
			ModifyTime: v.ModifyTime.Format(utils.FormatDateTime),
			Children:   nil,
		}
		list = append(list, tmp)
	}
	//组装返回值
	list = getDeptTreeRecursive(list, 0)
	return
}

func getDeptTreeRecursive(list []*system.DeptListItemResp, parentId int64) []*system.DeptListItemResp {
	res := make([]*system.DeptListItemResp, 0)
	for _, v := range list {
		if v.ParentId == parentId {
			v.Children = getDeptTreeRecursive(list, v.DeptId)
			res = append(res, v)
		}
	}
	return res
}

// DeleteDept 删除部门，连同删除子部门
func DeleteDept(req *system.DelSysDeptReq) (err error, errMsg string) {
	dept := new(system.SysDept)
	//找出当前层级，如果当前是最顶层，则批量删除和顶层相关的所有部门
	deptInfo, err := dept.GetDeptByDeptId(req.DeptId)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			errMsg = "部门不存在"
			err = errors.New(errMsg + "Err:" + err.Error())
			return
		}
		errMsg = "查询部门出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	admin := new(system.SysUser)
	var admins []*system.SysUser
	var depts []*system.SysDept
	var deptIdMap map[int64][]string
	if deptInfo.ParentId > 0 {
		//如果不是最顶层，则构建树形图，得到需要删除的dept_id
		//查询所有该顶层节点下的子节点
		deptIdMap, err, errMsg = GetChildDeptIds(deptInfo.RootId)
		if err != nil {
			return err, errMsg
		}

		deptIdArr := deptIdMap[deptInfo.DeptId]

		cond := " AND dept_id IN(" + strings.Join(deptIdArr, ",") + ")"
		pars := make([]interface{}, 0)

		//pars = append(pars, deptIdMap[deptInfo.DeptId])
		//验证是否存在绑定的员工账号
		admins, err = admin.GetAdminListByCondition(cond, pars)
		if err != nil {
			errMsg = "查询部门下的用户出错"
			err = errors.New(errMsg + "Err:" + err.Error())
			return
		}
		if len(admins) > 0 {
			errMsg = "该部门绑定了员工，不可删除"
			err = errors.New(errMsg)
			return
		}
		err = dept.DeleteByCondition(cond, pars)
	} else {
		//如果是最顶层，则删除所有相关的dept_id
		cond := " AND dept_id = ? OR root_id = ?"
		pars := make([]interface{}, 0)
		pars = append(pars, deptInfo.DeptId, deptInfo.DeptId)
		depts, err = dept.GetDeptListByCondition(cond, pars, "")
		if err != nil {
			errMsg = "查询部门信息出错"
			err = errors.New(errMsg + "Err:" + err.Error())
			return
		}
		var deptIds []string
		for _, v := range depts {
			deptIds = append(deptIds, strconv.Itoa(int(v.DeptId)))
		}
		//验证是否存在绑定的员工账号
		if len(deptIds) > 0 {
			aCond := " AND dept_id IN(" + strings.Join(deptIds, ",") + ")"
			aPars := make([]interface{}, 0)
			//aPars = append(aPars, deptIds)
			admins, err = admin.GetAdminListByCondition(aCond, aPars)
			if err != nil {
				errMsg = "查询部门下的员工出错"
				err = errors.New(errMsg + "Err:" + err.Error())
				return
			}
			if len(admins) > 0 {
				errMsg = "该部门绑定了员工，不可删除"
				err = errors.New(errMsg)
				return
			}
		}

		err = dept.DeleteByCondition(cond, pars)
	}
	return
}

func GetChildDeptIds(rootId int64) (deptIdMap map[int64][]string, err error, errMsg string) {
	dept := new(system.SysDept)
	fCondition := ""
	fPars := make([]interface{}, 0)
	if rootId > 0 {
		fCondition = " AND root_id = ? OR dept_id = ?"
		fPars = append(fPars, rootId, rootId)
	}

	orderStr := " level DESC"
	childList, tErr := dept.GetDeptListByCondition(fCondition, fPars, orderStr)
	if tErr != nil {
		errMsg = "查询部门列表出错"
		err = errors.New(errMsg + "Err:" + tErr.Error())
		return
	}

	deptIdMap = make(map[int64][]string)
	for _, v := range childList {

		deptIdMap[v.DeptId] = append(deptIdMap[v.DeptId], strconv.Itoa(int(v.DeptId)))
		if v.ParentId > 0 {
			deptIdMap[v.ParentId] = append(deptIdMap[v.ParentId], deptIdMap[v.DeptId]...)
		}
	}
	return
}

func GetChildDeptNames() (deptNameMap map[int64]string, err error, errMsg string) {
	dept := new(system.SysDept)
	fCondition := ""
	fPars := make([]interface{}, 0)

	orderStr := "level ASC"
	childList, tErr := dept.GetDeptListByCondition(fCondition, fPars, orderStr)
	if tErr != nil {
		errMsg = "查询部门列表出错"
		err = errors.New(errMsg + "Err:" + tErr.Error())
		return
	}

	deptNameMap = make(map[int64]string)
	for _, v := range childList {
		if v.ParentId > 0 {
			deptNameMap[v.DeptId] = deptNameMap[v.ParentId] + "/" + v.DeptName
		} else {
			deptNameMap[v.DeptId] = v.DeptName
		}
	}
	return
}

func DeptAdminTreeList() (list []*system.DeptAdminListItem, err error, errMsg string) {
	dept := new(system.SysDept)
	var condition string
	var pars []interface{}
	childList, err := dept.GetDeptListByCondition(condition, pars, "")
	if err != nil {
		errMsg = "查询部门列表出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	if len(childList) == 0 { //查不到相关记录
		return
	}
	// 查询管理员信息
	admin := new(system.SysUser)
	var list1 []*system.DeptAdminListItem
	adminList, err := admin.GetAdminListByCondition(condition, pars)
	adminMap := make(map[int64][]*system.DeptAdminListItem)
	for _, v := range adminList {
		tmp1 := &system.DeptAdminListItem{
			SysUserId: v.SysUserId,
			Name:      v.RealName,
			DeptId:    int64(v.SysUserId) + 1000,
			ParentId:  v.DeptId,
			Sort:      0,
			Children:  nil,
		}
		list1 = append(list1, tmp1)
	}
	list = make([]*system.DeptAdminListItem, 0)
	for _, v := range childList {
		tmp := &system.DeptAdminListItem{
			DeptId:   v.DeptId,
			Name:     v.DeptName,
			ParentId: v.ParentId,
			Sort:     v.Sort,
			Children: nil,
		}
		if c, ok := adminMap[v.DeptId]; ok {
			tmp.Children = c
		}
		list = append(list, tmp)
	}
	list = append(list, list1...)
	//组装返回值
	list = getDeptAdminTreeRecursive(list, 0)
	return
}

func getDeptAdminTreeRecursive(list []*system.DeptAdminListItem, parentId int64) []*system.DeptAdminListItem {
	res := make([]*system.DeptAdminListItem, 0)
	for _, v := range list {
		if v.ParentId == parentId {
			v.Children = getDeptAdminTreeRecursive(list, v.DeptId)
			res = append(res, v)
		}
	}
	return res
}

//获取部门及，部门下左右子节点的id
func GetDeptAllIds(rootId int64) (idArr []int64, err error) {
	dept := new(system.SysDept)
	fCondition := ""
	fPars := make([]interface{}, 0)
	//if rootId > 0 {
	//	fCondition = " AND root_id = ? OR dept_id = ?"
	//	fPars = append(fPars, rootId, rootId)
	//}
	orderStr := " level DESC"
	allDeptList, tErr := dept.GetDeptItemsByCondition(fCondition, fPars, orderStr)
	if tErr != nil {
		return
	}
	rootNode, err := dept.GetDeptItemByDeptId(rootId)
	if err != nil {
		return
	}
	sysDeptItemsMakeTree(allDeptList, rootNode)
	idArr = append(idArr, rootNode.DeptId)
	for _, nv := range rootNode.Children {
		idArr = append(idArr, nv.DeptId)
		for _, ncv := range nv.Children {
			idArr = append(idArr, ncv.DeptId)
		}
	}
	return
}

func chartDeptHaveChild(allNode []*system.DeptListItemResp, node *system.DeptListItemResp) (childs []*system.DeptListItemResp, yes bool) {
	for _, v := range allNode {
		if v.ParentId == node.DeptId {
			childs = append(childs, v)
		}
	}
	if len(childs) > 0 {
		yes = true
	}
	return
}

func sysDeptItemsMakeTree(allNode []*system.DeptListItemResp, node *system.DeptListItemResp) {
	childs, _ := chartDeptHaveChild(allNode, node) //判断节点是否有子节点并返回
	fmt.Println("node:", node.DeptId, node.DeptName, len(childs))
	if len(childs) > 0 {
		node.Children = append(node.Children, childs[0:]...) //添加子节点
		for _, v := range childs {                           //查询子节点的子节点，并添加到子节点
			_, has := chartDeptHaveChild(allNode, v)
			if has {
				sysDeptItemsMakeTree(allNode, v) //递归添加节点
			} else {
				childrenArr := make([]*system.DeptListItemResp, 0)
				v.Children = childrenArr
			}
		}
	} else {
		childrenArr := make([]*system.DeptListItemResp, 0)
		node.Children = childrenArr
	}
}

func getDeptNodeIds(node *system.DeptListItemResp, idArr []string) (ids []string) {
	ids = append(ids, strconv.Itoa(int(node.DeptId)))
	if len(node.Children) > 0 {
		for _, v := range node.Children {
			getDeptNodeIds(v, ids)
		}
	}
	ids = append(ids, idArr...)
	return ids
}
